package com.rest.common.utils;

import com.google.common.io.ByteStreams;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * 文件上传
 */
public class FileUploadUtils {

    private Logger logger = LoggerFactory.getLogger(FileUploadUtils.class);

    private static final long ONE_MB = 1048576l;

    public FileUploadUtils() {
    }

    /**
     * 文件上传
     *
     * @param request
     * @param response
     * @param filePath
     * @return
     * @throws Exception
     */
    public List<String> fileUpload(HttpServletRequest request, HttpServletResponse response, String filePath) throws Exception {
        return fileUpload(request, response, filePath, 10);
    }

    public List<String> fileUpload(HttpServletRequest request, HttpServletResponse response, String filePath, int customSize) throws Exception {
        ServletContext application = request.getSession().getServletContext();
        // 文件保存目录URL
        String saveUrl = request.getContextPath() + File.separator + filePath + File.separator;
        //        String savePath = InitializeApplicationProcessor.STATIC_FILE_PATH;
        String savePath = saveUrl;
        // 定义允许上传的文件扩展名
        HashMap<String, String> extMap = configExtensionName();
        // 最大文件大小10兆
        long maxSize = ONE_MB * customSize;
        response.setContentType("text/html; charset=UTF-8");
        if (!ServletFileUpload.isMultipartContent(request)) {
            return null;
        }
        // 检查目录
        File uploadDir = new File(savePath);
        if (!uploadDir.isDirectory()) {
            uploadDir.mkdirs();
        }
        // 检查目录写权限
        if (!uploadDir.canWrite()) {
            throw new Exception("上传目录没有写权限");
        }
        File saveDirFile = new File(savePath + saveUrl);
        if (!saveDirFile.exists()) {
            saveDirFile.mkdirs();
        }
        File dirFile = new File(savePath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        List<String> result = new ArrayList<>(); //返回结果
        try {
            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            //利用Spring的MultipartHttpServletRequest上传文件
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator item = multipartRequest.getFileNames();
            while (item.hasNext()) {
                String fileName = (String) item.next();
                List<MultipartFile> files = multipartRequest.getFiles(fileName);
                for (MultipartFile file : files) {
                    // 检查文件大小
                    if (file.getSize() > maxSize) {
                        throw new Exception("上传文件大小超过限制");
                    }
                    result.addAll(generateFileList(saveUrl, savePath, file));
                }
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("上传文件失败");
        }
    }




    private List<String> generateFileList(String saveUrl, String savePath, MultipartFile file) throws IOException {
        List<String> result = new ArrayList<>();
        logger.info("上传文件大小:" + file.getSize());
        // 检查扩展名
        String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
        File uploadedFile = new File(savePath + saveUrl, newFileName);
        InputStream inputStream = file.getInputStream();
        FileOutputStream fileOutputStream = new FileOutputStream(uploadedFile);
        Long size = ByteStreams.copy(inputStream, fileOutputStream);
        inputStream.close();
        fileOutputStream.close();
        logger.info("文件上传成功:" + savePath + saveUrl + newFileName + ",size:" + size);
        //上传图片保存路径
        String imageUrl = saveUrl + newFileName;
        imageUrl = imageUrl.replace("\\", "/");
        result.add(imageUrl);
        return result;
    }

    private HashMap<String, String> configExtensionName() {
        HashMap<String, String> extMap = new HashMap<>();
        extMap.put("image", "gif,jpg,jpeg,png,bmp");
        extMap.put("flash", "swf,flv");
        extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
        extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
        return extMap;
    }


    /**
     * 批量上传文件，返回文件路径以及原始文件名
     *
     * @param request
     * @param response
     * @param filePath
     * @return
     * @throws Exception
     */
    public Map<String, String> fileUploadw2Map(HttpServletRequest request, HttpServletResponse response, String filePath) throws Exception {
        // 文件保存目录URL
        String saveUrl = request.getContextPath() + File.separator + filePath + File.separator;
//        String savePath = InitializeApplicationProcessor.STATIC_FILE_PATH;
        String savePath = saveUrl;
        // 定义允许上传的文件扩展名
        HashMap<String, String> extMap = configExtensionName();
        // 最大文件大小 10兆
        long maxSize = 1048576 * 10;
        response.setContentType("text/html; charset=UTF-8");
        if (!ServletFileUpload.isMultipartContent(request)) {
            return null;
        }
        // 检查目录
        File uploadDir = new File(savePath);
        if (!uploadDir.isDirectory()) {
            uploadDir.mkdirs();
        }
        // 检查目录写权限
        if (!uploadDir.canWrite()) {
            throw new Exception("上传目录没有写权限");
        }
        File saveDirFile = new File(savePath + saveUrl);
        if (!saveDirFile.exists()) {
            saveDirFile.mkdirs();
        }
        File dirFile = new File(savePath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        Map<String, String> resultMap = new HashMap<String, String>();//返回结果
        try {
            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            //利用Spring的MultipartHttpServletRequest上传文件
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator item = multipartRequest.getFileNames();
            while (item.hasNext()) {
                String fileName = (String) item.next();
                List<MultipartFile> files = multipartRequest.getFiles(fileName);
                for (MultipartFile file : files) {
                    // 检查文件大小
                    if (file.getSize() > maxSize) {
                        throw new Exception("上传文件大小超过限制");
                    }
                    // 检查扩展名
                    String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                    String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
                    File uploadedFile = new File(savePath + saveUrl, newFileName);
                    ByteStreams.copy(file.getInputStream(), new FileOutputStream(uploadedFile));
                    //上传图片保存路径
                    String imageUrl = saveUrl + newFileName;
                    imageUrl = imageUrl.replace("\\", "/");
                    //key:原始文件名  value:上传后文件路径+修改后文件名
                    resultMap.put(file.getOriginalFilename().split("\\.")[0], imageUrl);
                }
            }
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("上传文件失败");
        }
    }

    /**
     * 上传安卓app文件（不改变文件名称）
     *
     * @param request
     * @param response
     * @param filePath
     * @return
     * @throws Exception
     */
    public String fileUploadw2Filename(HttpServletRequest request, HttpServletResponse response, String filePath) throws Exception {
        // 文件保存目录URL
        String saveUrl = request.getContextPath() + File.separator + filePath + File.separator;
        //        String savePath = InitializeApplicationProcessor.STATIC_FILE_PATH;
        String savePath = saveUrl;
        // 定义允许上传的文件扩展名
        HashMap<String, String> extMap = new HashMap<String, String>();
        extMap.put("file", "apk");
        long maxSize = 1048576 * 20;
        response.setContentType("text/html; charset=UTF-8");
        if (!ServletFileUpload.isMultipartContent(request)) {
            return null;
        }
        // 检查目录
        File uploadDir = new File(savePath);
        if (!uploadDir.isDirectory()) {
            uploadDir.mkdirs();
        }
        // 检查目录写权限
        if (!uploadDir.canWrite()) {
            throw new Exception("上传目录没有写权限");
        }
        File saveDirFile = new File(savePath + saveUrl);
        if (!saveDirFile.exists()) {
            saveDirFile.mkdirs();
        }
        File dirFile = new File(savePath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        Map<String, String> resultMap = new HashMap<String, String>();//返回结果
        try {
            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            //利用Spring的MultipartHttpServletRequest上传文件
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator item = multipartRequest.getFileNames();
            String newFileName = "";
            while (item.hasNext()) {
                String fileName = (String) item.next();
                List<MultipartFile> files = multipartRequest.getFiles(fileName);
                for (MultipartFile file : files) {
                    // 检查文件大小
                    if (file.getSize() > maxSize) {
                        throw new Exception("上传文件大小超过限制");
                    }
                    //保持文件名不变
                    String originalFileName = file.getOriginalFilename(); //原始文件名包括扩展名
                    newFileName = file.getOriginalFilename().split("\\.")[0]; //去掉扩展名
                    File uploadedFile = new File(savePath + saveUrl, originalFileName);
                    ByteStreams.copy(file.getInputStream(), new FileOutputStream(uploadedFile));
                }
            }
            return newFileName;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("上传文件失败");
        }
    }

}
